package org.framework.core.override.context;

import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.framework.core.asm.adapter.ClassAdapter;
import org.framework.core.asm.adapter.ServiceAdapter;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;


public class ContextRegister {
	
	private final Logger log = LogManager.getLogger(ContextRegister.class);
			
	public static ApplicationContext CONTEXT;

	private ContextRegister(ApplicationContext applicationContext){
		ContextRegister.CONTEXT = applicationContext;
	}
	
	public static ContextRegister createContextRegister(ApplicationContext applicationContext) {
		return new ContextRegister(applicationContext);
	}
	
	public void initContextRegister() {
		registService();
	}
	
	protected void registService() {
		log.info("regist [@ServiceMethod] to Spring beanFactory");
		
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) CONTEXT.getAutowireCapableBeanFactory();
		
		Map<String, Object> beanMap = CONTEXT.getBeansWithAnnotation(Service.class);
		
		ClassAdapter adapter = new ServiceAdapter();
		
		for (Map.Entry<String, Object> entry : beanMap.entrySet()) {
			
			Map<String, Object> serviceBeanMap = adapter.resolve(entry.getValue().getClass().getSuperclass());

			for (Map.Entry<String, Object> entry1: serviceBeanMap.entrySet()) {
				
				log.info("regist bean info:[{}={}]", entry1.getKey(), entry1.getValue().getClass().getName());
				
				BeanDefinitionBuilder bean = BeanDefinitionBuilder.genericBeanDefinition(entry1.getValue().getClass());
				bean.setScope("prototype");
				bean.addPropertyReference("serviceDao", "serviceDao");
				
				beanFactory.registerBeanDefinition(entry1.getKey(), bean.getRawBeanDefinition());
			}
		}
	}
	
}
